package fatworm.storage.table;

import java.util.*;

import fatworm.query.constant.*;
import fatworm.storage.types.*;

public class Schema
{
    private HashMap<String, SType> info = new HashMap<String, SType>();
    private HashMap<String, Integer> addOrder = new HashMap<String, Integer>();
    private int addCount = 0;

    public Schema()
    {
    }
    public void addDefVal(String fldname, SType defVal)
    {
        info.put(fldname, defVal);
        addOrder.put(fldname, ++addCount);
    }
    public void addField(String fldname, int type, int length, Constant defConst)
    {
        SType defVal;
        switch (type)
        {
            case Types.INT :
                defVal = new SInt();
                break;
            case Types.VARCHAR :
                defVal = new SVarChar(length);
                break;
            default :
                throw new Error("TODO"); // TODO
        }
        defVal.fromConstant(defConst);
        this.addDefVal(fldname, defVal);
    }
    public void addField(String fldname, int type, int length)
    {
        this.addField(fldname, type, length, new NullConstant());
    }
    public void add(String fldname, Schema sch)
    {
        this.addDefVal(fldname, sch.type(fldname).copy());
    }
    public void add(Collection<String> subset, Schema sch)
    {
        for (String fldname : subset)
            add(fldname, sch);
    }
    public void addAll(Schema sch)
    {
        for (String fldname : sch.fields())
            add(fldname, sch);
    }
    public void renameField(String oldName, String newName)
    {
        SType fi = info.get(oldName);
        if (fi == null)
            throw new Error("!!!");
        Integer fo = addOrder.get(oldName);
        if (fo == null)
            throw new Error("!!!");
        info.remove(oldName);
        addOrder.remove(oldName);
        info.put(newName, fi);
        addOrder.put(newName, fo);
    }
    public Collection<String> fields()
    {
        ArrayList<String> res = new ArrayList<String>();
        res.addAll(info.keySet());
        Comparator<String> cmp = new Comparator<String>()
        {
            public int compare(String arg0, String arg1)
            {
                return addOrder.get(arg0) - addOrder.get(arg1);
            }
        };
        Collections.sort(res, cmp);
        return res;
    }
    public boolean hasField(String fldname)
    {
        return info.containsKey(fldname);
    }
    public SType type(String fldname)
    {
        return info.get(fldname);
    }
}
